<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.6.3" />
<title>Gerrit Code Review - Single Sign-On Security</title>
<style type="text/css">
/* Sans-serif font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
div#toctitle,
span#author, span#revnumber, span#revdate, span#revremark,
div#footer {
  font-family: Arial,Helvetica,sans-serif;
}

/* Serif font. */
div.sectionbody {
  font-family: Georgia,"Times New Roman",Times,serif;
}

/* Monospace font. */
tt {
  font-size: inherit;
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  font-size: inherit;
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}
ul > li     { color: #aaa; }
ul > li > * { color: black; }

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
}

div#footer {
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid #dddddd;
  border-left: 4px solid #f0f0f0;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid #dddddd;
  border-left: 5px solid #f0f0f0;
  background: #f8f8f8;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #f0f0f0;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
  font-size: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-weight: bold;
  color: #527bbd;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}

div.colist td {
  padding-right: 0.5em;
  padding-bottom: 0.3em;
  vertical-align: top;
}
div.colist td img {
  margin-top: 0.3em;
}

@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}

</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>Gerrit Code Review - Single Sign-On Security</h1>
<span id="revnumber">version 2.5</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Gerrit supports integration with some types of single sign-on
security solutions, making it possible for end-users to setup
and manage accounts, without administrator involvement.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_openid">OpenID</h2>
<div class="sectionbody">
<div class="paragraph"><p>By default a new Gerrit installation relies upon OpenID to perform
user authentication services.  To enable OpenID, the auth.type
setting should be <tt>OpenID</tt>:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>git config --file $site_path/etc/gerrit.config auth.type OpenID</tt></pre>
</div></div>
</div></div>
<div class="paragraph"><p>As this is the default setting there is nothing required from the
site administrator to make use of the OpenID authentication services.</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://openid.net/">openid.net</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>If Jetty is being used, you may need to increase the header
buffer size parameter, due to very long header lines.
Add the following to <tt>$JETTY_HOME/etc/jetty.xml</tt> under
<tt>org.mortbay.jetty.nio.SelectChannelConnector</tt>:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>&lt;Set name="headerBufferSize"&gt;16384&lt;/Set&gt;</tt></pre>
</div></div>
</div></div>
<div class="paragraph"><p>In order to use permissions beyond those granted to the
<tt>Anonymous Users</tt> and <tt>Registered Users</tt> groups, an account
must only have OpenIDs which match at least one pattern from the
<tt>auth.trustedOpenID</tt> list in <tt>gerrit.config</tt>.  Patterns may be
either a
<a href="http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html">standard
Java regular expression (java.util.regex)</a> (must start with <tt>^</tt>
and end with <tt>$</tt>) or be a simple prefix (any other string).</p></div>
<div class="paragraph"><p>Out of the box Gerrit is configured to trust two patterns, which
will match any OpenID provider on the Internet:</p></div>
<div class="ulist"><ul>
<li>
<p>
<tt>http://</tt>&#8201;&#8212;&#8201;trust all OpenID providers using the HTTP protocol
</p>
</li>
<li>
<p>
<tt>https://</tt>&#8201;&#8212;&#8201;trust all OpenID providers using the HTTPS protocol
</p>
</li>
</ul></div>
<div class="paragraph"><p>To trust only Google Accounts:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>git config --file $site_path/etc/gerrit.config auth.trustedOpenID 'https://www.google.com/accounts/o8/id?id='</tt></pre>
</div></div>
</div></div>
<div class="sect2">
<h3 id="_database_schema">Database Schema</h3>
<div class="paragraph"><p>User identities obtained from OpenID providers are stored into the
<tt>account_external_ids</tt> table.  Users may link more than one OpenID
identity to the same Gerrit account (use Settings, Web Identities
to manage this linking), making it easier for their browser to sign
in to Gerrit if they are frequently switching between different
unique OpenID accounts.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_http_basic_digest_authentication">HTTP Basic/Digest Authentication</h2>
<div class="sectionbody">
<div class="paragraph"><p>When using HTTP authentication, Gerrit assumes that the servlet
container or the frontend web server has performed all user
authentication prior to handing the request off to Gerrit.</p></div>
<div class="paragraph"><p>As a result of this assumption, Gerrit can assume that any and
all requests have already been authenticated.  The "Sign In" and
"Sign Out" links are therefore not displayed in the web UI.</p></div>
<div class="paragraph"><p>To enable this form of authentication:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>git config --file $site_path/etc/gerrit.config auth.type HTTP
git config --file $site_path/etc/gerrit.config --unset auth.httpHeader
git config --file $site_path/etc/gerrit.config auth.emailFormat '{0}@example.com'</tt></pre>
</div></div>
</div></div>
<div class="paragraph"><p>The auth.type must always be HTTP, indicating the user identity
will be obtained from the HTTP authorization data.</p></div>
<div class="paragraph"><p>The auth.httpHeader must always be unset.  If set to any value
(including <tt>Authorization</tt>) then Gerrit won&#8217;t correctly honor the
standard <tt>Authorization</tt> HTTP header.</p></div>
<div class="paragraph"><p>The auth.emailFormat field (<em>optional</em>) sets the preferred email
address during first login.  Gerrit will replace <tt>{0}</tt> with the
username, as obtained from the Authorization header.  A format such
as shown in the example would be typical, to add the domain name
of the organization.</p></div>
<div class="paragraph"><p>If Apache HTTPd is being used as the primary web server and the
Apache server will be handling user authentication, a configuration
such as the following is recommended to ensure Apache performs the
authentication at the proper time:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>&lt;Location "/login/"&gt;
  AuthType Basic
  AuthName "Gerrit Code Review"
  Require valid-user
  ...
&lt;/Location&gt;</tt></pre>
</div></div>
</div></div>
<div class="sect2">
<h3 id="_database_schema_2">Database Schema</h3>
<div class="paragraph"><p>User identities are stored in the <tt>account_external_ids</tt> table.
The user string obtained from the authorization header has the prefix
"gerrit:" and is stored in the <tt>external_id</tt> field.  For example,
if a username was "foo" then the external_id field would be populated
with "gerrit:foo".</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_computer_associates_siteminder">Computer Associates Siteminder</h2>
<div class="sectionbody">
<div class="paragraph"><p>Siteminder is a commercial single sign on solution marketed by
Computer Associates.  It is very common in larger enterprise
environments.</p></div>
<div class="paragraph"><p>When using Siteminder, Gerrit assumes it has been installed in a
servlet container which is running behind an Apache web server,
and that the Siteminder authentication module has been configured
within Apache to protect the entire Gerrit application.  In this
configuration all users must authenticate with Siteminder before
they can access any resource on Gerrit.</p></div>
<div class="paragraph"><p>As a result of this assumption, Gerrit can assume that any and
all requests have already been authenticated.  The "Sign In" and
"Sign Out" links are therefore not displayed in the web UI.</p></div>
<div class="paragraph"><p>To enable this form of authentication:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>git config --file $site_path/etc/gerrit.config auth.type HTTP
git config --file $site_path/etc/gerrit.config auth.httpHeader SM_USER
git config --file $site_path/etc/gerrit.config auth.emailFormat '{0}@example.com'</tt></pre>
</div></div>
</div></div>
<div class="paragraph"><p>The auth.type must always be HTTP, indicating the user identity
will be obtained from the HTTP authorization data.</p></div>
<div class="paragraph"><p>The auth.httpHeader indicates in which HTTP header field the Siteminder
product has stored the username.  Usually this is "SM_USER", but
may differ in your environment.  Please refer to your organization&#8217;s
single sign-on or security group to ensure the setting is correct.</p></div>
<div class="paragraph"><p>The auth.emailFormat field (<em>optional</em>) sets the user&#8217;s preferred
email address when they first login.  Gerrit will replace <tt>{0}</tt>
with the username, as supplied by Siteminder.  A format such as
shown in the example would be typical, to add the domain name of
the organization.</p></div>
<div class="paragraph"><p>If Jetty is being used, you may need to increase the header
buffer size parameter, due to very long header lines.
Add the following to <tt>$JETTY_HOME/etc/jetty.xml</tt> under
<tt>org.mortbay.jetty.nio.SelectChannelConnector</tt>:</p></div>
<div class="exampleblock">
<div class="content">
<div class="literalblock">
<div class="content">
<pre><tt>&lt;Set name="headerBufferSize"&gt;16384&lt;/Set&gt;</tt></pre>
</div></div>
</div></div>
<div class="sect2">
<h3 id="_database_schema_3">Database Schema</h3>
<div class="paragraph"><p>User identities are stored in the <tt>account_external_ids</tt> table.
The user string obtained from Siteminder (e.g. the value in the
"SM_USER" HTTP header) has the prefix "gerrit:" and is stored in the
<tt>external_id</tt> field.  For example, if a Siteminder username was "foo"
then the external_id field would be populated with "gerrit:foo".</p></div>
</div>
</div>
</div>
<hr style="
  height: 2px;
  color: silver;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
">
<div class="paragraph"><p>Part of <a href="index.html">Gerrit Code Review</a></p></div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Version 2.5<br />
Last updated 2012-10-25 21:09:05 CEST
</div>
</div>
</body>
</html>
